package com.example.scaffold_demo.db;

import android.content.Context;


import com.example.databaselibrary.db.IDataSourceOperation;
import com.example.scaffold_demo.db.greendao.DaoMaster;
import com.example.scaffold_demo.db.greendao.DaoSession;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.identityscope.IdentityScopeType;

import java.util.List;


/**
 * Created by VIVEK-WO on 2018/3/29.
 */

public class DBManager implements IDataSourceOperation {
    private static final String DATABASE_NAME = "local.db";//数据库名称
    private static final String DATABASE_PASSWORD="123456";
    DaoSession mDaoSession;
    private volatile static DBManager mSingleton = null;

    public static DBManager getInstance(Context mContest) {
        // 这个方法比上面有所改进，不用每次都进行生成对象，只是第一次
        // 使用时生成实例，提高了效率！
        if (mSingleton == null) {
            synchronized (DBManager.class) {
                if (mSingleton == null) {
                    mSingleton = new DBManager(mContest);
                }
            }
        }
        return mSingleton;
    }

    public DBManager(Context context) {

        DatabaseOpenHelper mSQLiteOpenHelper = new DatabaseOpenHelper(context,DATABASE_NAME);//建库
        // greendao 操作数据库时 用这个方法 打开加密的库
        // openHelper.getEncryptedWritableDb(Contents.DB_KEY);  获取可读可写数据库
        // openHelper.getEncryptedReadableDb(Contents.DB_KEY);  获取可读数据库
        DaoMaster mDaoMaster = new DaoMaster(mSQLiteOpenHelper.getEncryptedWritableDb(DATABASE_PASSWORD));//加密
        mDaoSession = mDaoMaster.newSession(IdentityScopeType.None);
    }


    public AbstractDao<?, ?> getDao(Class<? extends Object> entityClass) {
        return mDaoSession.getDao(entityClass);
    }

    @Override
    public void insert(Object object) {
        Class cls;
        if (object instanceof List) {
            List listObject = (List) object;
            if (listObject.isEmpty()) {
                throw new IllegalArgumentException("List Object Not Allow Empty!");
            }
            cls = listObject.get(0).getClass();
            getDao(cls).insertInTx(listObject);
        } else {
            cls = object.getClass();
            getDao(cls).insert(object);
        }
    }

    @Override
    public void insertOrUpdate(Object object) {
        Class cls;
        if (object instanceof List) {
            List listObject = (List) object;
            if (listObject.isEmpty()) {
                throw new IllegalArgumentException("List Object Not Allow Empty!");
            }
            cls = listObject.get(0).getClass();
            getDao(cls).insertOrReplaceInTx(listObject);
        } else {
            cls = object.getClass();
            getDao(cls).insertOrReplace(object);
        }
    }

    @Override
    public void update(Object object) {
        Class cls;
        if (object instanceof List) {
            List listObject = (List) object;
            if (listObject.isEmpty()) {
                throw new IllegalArgumentException("List Object Not Allow Empty!");
            }
            cls = listObject.get(0).getClass();
            getDao(cls).updateInTx(listObject);
        } else {
            cls = object.getClass();
            getDao(cls).update(object);
        }
    }

    @Override
    public void delete(Object object) {
        Class cls;
        if (object instanceof List) {
            List listObject = (List) object;
            if (listObject.isEmpty()) {
                throw new IllegalArgumentException("List Object Not Allow Empty!");
            }
            cls = listObject.get(0).getClass();
            getDao(cls).deleteInTx(listObject);
        } else {
            cls = object.getClass();
            getDao(cls).delete(object);
        }
    }

    @Override
    public void deleteByKey(Class<?> cls, String key) {
        ((AbstractDao<?, String>) getDao(cls)).deleteByKey(key);
    }

    @Override
    public void deleteAll(Class<?> cls) {
        getDao(cls).deleteAll();
    }

    @Override
    public <T> T quaryByKey(Class<T> cls, String key) {
        return ((AbstractDao<T, String>) getDao(cls)).load(key);
    }

    @Override
    public <T> List<T> quary(Class<T> cls, String where, String... selectionArg) {
        return ((AbstractDao<T, String>) getDao(cls)).queryRaw(where, selectionArg);
    }

    @Override
    public <T> List<T> quaryAll(Class<T> cls) {
        return ((AbstractDao<T, String>) getDao(cls)).loadAll();
    }


}
